#include "process_pool.h"

int main(int argc, char ** argv)
{
    //ip port processnum
    ARGS_CHECK(argc, 4);
    int processNum = atoi(argv[3]);
    process_data * pProcess = calloc(processNum, sizeof(process_data));
    //创建N个子进程
    makeChild(pProcess, processNum);

    //创建监听的服务器
    int listenfd = tcpInit(argv[1], atoi(argv[2]));

    //创建epoll的实例
    int epfd = epoll_create1(0);
    ERROR_CHECK(epfd, -1, "epfd");
    //epoll监听Listenfd
    epollAddReadEvent(epfd, listenfd);
    ///epoll监听父子进程间通信的管道
    for(int i = 0; i < processNum; ++i) {
        epollAddReadEvent(epfd, pProcess[i].pipefd);
    }
    //定义保存就绪的文件描述符的数组
    struct epoll_event eventArr[10] = {0};
    int nready = 0;

    while(1)
    {
        nready = epoll_wait(epfd, eventArr, sizeof(eventArr), -1);
        for(int i = 0; i < nready; ++i) {
            int fd = eventArr[i].data.fd; 
            //新客户端到来
            if(fd == listenfd) {
                struct sockaddr_in clientaddr;
                socklen_t len = sizeof(clientaddr);
                int peerfd = accept(listenfd, (struct sockaddr*)&clientaddr, &len);
                ERROR_CHECK(peerfd, -1, "accept");
                printf("client %s:%d connected.\n",
                       inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                //将peerfd发送给一个空闲的子进程
                for(int j = 0; j < processNum; ++j) {
                    if(pProcess[j].status == FREE) {
                        sendFd(pProcess[j].pipefd, peerfd);
                        pProcess[j].status = BUSY;
                        break;
                    }
                }
                //如果要断开与客户端的连接，这里还得执行一次
                close(peerfd);
            } else {
                //管道发生了事件: 子进程已经执行完任务了
                int howmany = 0;
                read(fd, &howmany, sizeof(howmany));
                for(int j = 0; j < processNum; ++j) {
                    if(pProcess[j].pipefd == fd) {
                        pProcess[j].status = FREE;
                        printf("child %d is not busy.\n", pProcess[j].pid);
                        break;
                    }
                }

            }
        }
    }
    close(listenfd);
    close(epfd);

    return 0;
}

